/**
 * Lenovo Group
 * Copyright (c) 1999-2016 All Rights Reserved.
 */
package com.lenovo.lmrp.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.lenovo.sdc.framework.util.AttributeBean;
import com.lenovo.sdc.framework.util.CommonUtil;

/**
 * 
 * @author wujin
 * @version v1.0
 */
public abstract class ABaseMain {
    protected static final Arguments arguments = new Arguments();

    public abstract void initialize() throws Exception;
    
    protected JCommander parseCommand(String[] args) {
        // constructe command parser to handle user input command line argument
        JCommander commander = new JCommander(arguments);

        // parse failed will show help to user
        try {
            commander.parse(args);
        }
        catch (Exception exp) {
            System.out.println("parse command meet error:" + exp.getMessage());
            commander.usage();
            System.exit(0);
        }

        // help command
        if (arguments.help) {
            commander.usage();
            System.exit(0);
        }

        // version command
        if (arguments.version) {
            showVersion();
            System.exit(0);
        }
        
        return commander;
    }
    
    /**
     * read version information from version.info file that is under META-INF folder in jar file
     */
    protected void showVersion() {
        try (InputStream in = Thread.currentThread().getContextClassLoader()
            .getResourceAsStream("META-INF/version.info")) {
            int len = 0;
            byte[] buf = new byte[256];
            StringBuilder sb = new StringBuilder();
            
            while ((len = in.read(buf)) > 0)
                sb.append(new String(buf, 0, len, "UTF-8"));

            System.out.println(sb.toString());
        }
        catch (Exception exp) {
            System.out.println(exp.getMessage());
        }
    }
    
    /**
     * locate configuration file, if user doesn't set path at command line find in root-classpath/config
     * 
     * @return
     */
    protected File getConfigurationFile(String fileName) {
        File configFile;
        // 
        if (CommonUtil.isNullOrEmpty(arguments.configurationPath)) {
            String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
            configFile = new File(path + File.separatorChar + "config" + File.separatorChar + fileName);
        }
        else {
            if (arguments.configurationPath.endsWith("/")
                            || arguments.configurationPath.endsWith("\\"))
                configFile = new File(arguments.configurationPath + fileName);
            else
                configFile = new File(arguments.configurationPath + File.separatorChar + fileName);
        }
        return configFile;
    }
    
    protected AttributeBean loadProperties(String fileName) throws Exception {
        File configFile = getConfigurationFile(fileName);
        if (configFile.exists() == false)
            throw new Exception("not found configuration file " + configFile.getAbsolutePath());
        
        // load properties data to create AttributeBean object
        FileInputStream in = null;
        Properties props = new Properties();
        try {
            in = new FileInputStream(configFile);
            props.load(in);
            in.close();
            return new AttributeBean(props);
        }
        finally {
            CommonUtil.closeIO(in);
        }
    }
    
    protected static class Arguments {
        @Parameter(names = "-f", description = "The path of custom configuration files")
        private String configurationPath;

        @Parameter(names = { "-v", "--version" }, description = "Show version.", help = true)
        private boolean version;

        @Parameter(names = { "-h", "--help" }, description = "Help message.", help = true)
        private boolean help;
    }
}
